package com.xjy.ftpmanagment.command;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xjy.common.util.PathUtil;
import com.xjy.common.util.StringUtil;
import com.xjy.ftpmanagment.pojo.StatFile;
import com.xjy.ftpmanagment.pojo.StatIp;
import com.xjy.ftpmanagment.pojo.StatUser;
import com.xjy.ftpmanagment.service.StatService;
import com.xjy.ftpmanagment.service.StatUserService;

public class ExecSustat {
	private static final Log logger = LogFactory.getLog(ExecSustat.class);
	
	private static final String STAT_TAG = "________";
	private static final String CMD_BASE = "cmd.exe /c " + PathUtil.getContextPath() + "sustat/sustat.exe ";
	private static final String CMD_FILE= " -f ";		// 文件下载次数
	private static final String CMD_DIR_FILE= " -d ";	// 目录，文件下载数目排行
	private static final String CMD_DIR_MB= " -D ";		// 目录，文件下载量排行
	private static final String CMD_IP_MB= " -h ";		// IP，下载量排行
	private static final String CMD_IP_CONN= " -H ";	// IP，登陆次数排行

	private static final long ONE_DAY = 24 * 60 * 60 * 1000;
	// 日志文件名
	private DateFormat formatter;
	private String fileName;
	// 日志时间段
	private Timestamp startTime;
	private Timestamp endTime;
	
	// service
	private StatService statService;
	private StatUserService statUserService;
	
	public StatService getStatService() {
		return statService;
	}

	public void setStatService(StatService statService) {
		this.statService = statService;
	}
	
	public StatUserService getStatUserService() {
		return statUserService;
	}

	public void setStatUserService(StatUserService statUserService) {
		this.statUserService = statUserService;
	}

	public void exec(String[] args) throws Exception {
		genFileName();
		genTime();
		if(!(new File(fileName).exists())) {
			logger.info("log file <<" + fileName + ">> not exist, return ");
			return;
		}
		logger.info("-----> start to exec sustat task, log file is " + fileName);
		logger.info("CMD_BASE is: " + CMD_BASE);
		cmdUser();
		cmdFile(20);
		cmdIp();
		logger.info("-----> finish sustat task, log file is " + fileName);
	}

	private void genTime() {
		Calendar today = new GregorianCalendar();
		today.set(Calendar.HOUR_OF_DAY, 0);
		today.set(Calendar.MINUTE, 0);
		today.set(Calendar.SECOND, 0);
		today.set(Calendar.MILLISECOND, 0);
		endTime = new Timestamp(today.getTimeInMillis());
		today.add(Calendar.DAY_OF_YEAR, -1);
		startTime = new Timestamp(today.getTimeInMillis());
	}

	/**
	 * 生成日志文件名称
	 */
	private void genFileName() {
		try {
			formatter = new SimpleDateFormat(SustatConstant.FTP_LOG_FILE_FORMAT, Locale.ENGLISH);
		} catch(Exception ex) {
			formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
		}
		Date yes = new Date(System.currentTimeMillis() - (24 * 3600 * 1000));
		fileName = SustatConstant.FTP_LOG_PATH + SustatConstant.FTP_LOG_FILE.replace("<date>",formatter.format(yes));
	}

	/**
	 * 按账号统计连接次数、下载/上传文件数、以及文件大小、所占比例
	 * @throws Exception
	 */
	private void cmdUser() throws Exception {
		Process process = Runtime.getRuntime().exec(CMD_BASE + fileName);
		InputStream inputStream = process.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
		process.getOutputStream().close();

		String line = null;
		while ((line = reader.readLine()) != null) {
			line = line.trim();
			if (line.startsWith(STAT_TAG)) {
				List<StatUser> statUserList = new ArrayList<StatUser>();
				while (!(line = reader.readLine()).startsWith(STAT_TAG)) {
					line = line.trim();
					String[] res = line.split("\\s+");
					if(res.length == 9) {
						logger.info("Sustat User 解析--->" + Arrays.toString(res));
						StatUser  po = new StatUser();
						po.setUser(res[1]);
						po.setConn(StringUtil.parseInt(res[2]));
						po.setDownFile(StringUtil.parseInt(res[3]));
						po.setDownMb(StringUtil.parseDouble(res[4]));
						po.setDownPercent(StringUtil.parseDouble(res[5].substring(0, res[5].length() - 1)));
						po.setUpFile(StringUtil.parseInt(res[6]));
						po.setUpMb(StringUtil.parseDouble(res[7]));
						po.setUpPercent(StringUtil.parseDouble(res[8].substring(0, res[8].length() - 1)));
						po.setStatTime(new Timestamp(System.currentTimeMillis() - ONE_DAY));
						po.setCreateTime(new Timestamp(System.currentTimeMillis()));
						// statUserService.getStatUserDao().save(po);
						statUserList.add(po);
					} else {
						logger.error("Sustat User 解析结果出错--->" + Arrays.toString(res));
					}
				}
				if(statUserList.size() > 0) {
					logger.info("批量写入下载文件数统计List<StatUser>，size = " + statUserList.size());
					statUserService.batchInsertStatUser(statUserList, startTime, endTime);
				}
				
			}
		}
	}

	/**
	 * 统计文件下载数
	 * @param count	列出下载次数最多的count条记录
	 * @throws Exception
	 */
	private void cmdFile(int count) throws Exception {
		Process process = Runtime.getRuntime().exec(CMD_BASE + fileName + CMD_FILE + count);
		InputStream inputStream = process.getInputStream();
		// 注意这里必须GB2312，否则中文乱码
		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GB2312"));
		process.getOutputStream().close();
		
		String line = null;
		int statTagCount = 0;
		while ((line = reader.readLine()) != null) {
			line = line.trim();
			if (line.startsWith(STAT_TAG)) {
				statTagCount++;
				if(statTagCount++ < 2)
					continue;
				List<StatFile> statFileList = new ArrayList<StatFile>();
				while (!(line = reader.readLine()).startsWith(STAT_TAG)) {
					line = line.trim();
					String[] res = line.split("\\s+");
					logger.info("Sustat File 解析--->" + Arrays.toString(res));
					StatFile po = new StatFile();
					po.setFileCount(Integer.parseInt(res[1]));
					// 处理文件名中带有空格的情况
//					StringBuilder builder = new StringBuilder();
//					for (int i = 2; i < res.length; i++) {
//						builder.append(res[i]);
//					}
//					po.setFileName(builder.toString());
					po.setFileName(line.substring(line.indexOf(" x ") + 3));
					po.setStatTime(new Timestamp(System.currentTimeMillis() - ONE_DAY));
					po.setCreateTime(new Timestamp(System.currentTimeMillis()));
					statFileList.add(po);
				}
				if(statFileList.size() > 0) {
					logger.info("批量写入下载文件数统计List<StatFile>，size = " + statFileList.size());
					statService.batchInsertStatFile(statFileList, startTime, endTime);
				}
			}
		}
	}
	
	@SuppressWarnings("unused")
	// 按照目录统计，统计目录下文件下载数目排行
	private void cmdDirFile() throws Exception {
	}
	
	@SuppressWarnings("unused")
	// 按照目录统计，统计目录下文件下载大小排行
	private void cmdDirMb() throws Exception {
	}
	
	/**
	 * 按IP地址统计连接次数、下载/上传文件数、以及文件大小、所占比例
	 * 按照下载文件大小排序
	 * @throws Exception
	 */
	private void cmdIp() throws Exception {
		Process process = Runtime.getRuntime().exec(CMD_BASE + fileName + CMD_IP_MB);
		InputStream inputStream = process.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
		process.getOutputStream().close();
		
		String line = null;
		while ((line = reader.readLine()) != null) {
			line = line.trim();
			if (line.startsWith(STAT_TAG)) {
				List<StatIp> statIpList = new ArrayList<StatIp>();
				while (!(line = reader.readLine()).startsWith(STAT_TAG)) {
					line = line.trim();
					String[] res = line.split("\\s+");
					logger.info("Sustat Ip 解析--->" + Arrays.toString(res));
					StatIp po = new StatIp();
					po.setIp(res[1]);
					po.setConn(StringUtil.parseInt(res[2]));
					po.setDownFile(StringUtil.parseInt(res[3]));
					po.setDownMb(StringUtil.parseDouble(res[4]));
					po.setDownPercent(StringUtil.parseDouble(res[5].substring(0, res[5].length() - 1)));
					po.setUpFile(StringUtil.parseInt(res[6]));
					po.setUpMb(StringUtil.parseDouble(res[7]));
					po.setUpPercent(StringUtil.parseDouble(res[8].substring(0, res[8].length() - 1)));
					po.setStatTime(new Timestamp(System.currentTimeMillis() - ONE_DAY));
					po.setCreateTime(new Timestamp(System.currentTimeMillis()));
					statIpList.add(po);
				}
				if(statIpList.size() > 0) {
					logger.info("批量写入下载文件数统计List<statIp>，size = " + statIpList.size());
					statService.batchInsertStatIp(statIpList, startTime, endTime);
				}
			}
		}
	}
}
